/*=========================================================================

Program:   Virtual Surgery
Language:  C++
Date:      2009-12-7
Version:   0.1
Mail:		   nelfylee@gmail.com

Copyright (c) 2009 Nelfy Lee. All rights reserved.

=========================================================================*/
#include "VolumePanel.h"



VolumePanel::VolumePanel(QWidget *parent) : ControlPanelBase(parent)
{
	m_ui.setupUi(this);
	m_panelType=ptVolume;
	m_volume1=NULL;
	m_volume2=NULL;
	m_vsource=NULL;

	QVBoxLayout *vbox = new QVBoxLayout(m_ui.group_rendering);
	vbox->setSpacing(4);
	vbox->setMargin(4);

	m_colorEditor = new ShadeWidget(ShadeWidget::ARGBShade, m_ui.group_rendering);
	m_opacityEditor = new ShadeWidget(ShadeWidget::ARGBShade, m_ui.group_rendering);

	vbox->addWidget(m_colorEditor);
	vbox->addWidget(m_opacityEditor);

	connect(m_colorEditor, SIGNAL(pointsChanged()), this, SLOT(slotColorChanged()));
	connect(m_opacityEditor, SIGNAL(pointsChanged()), this, SLOT(slotOpacityChanged()));

	connect(m_ui.btn_volumeCalculation, SIGNAL(clicked()), SLOT(slotVolumeCalculation()));
	connect(m_ui.btn_plus, SIGNAL(clicked()), SLOT(slotPLUS()));
	connect(m_ui.btn_minus, SIGNAL(clicked()), SLOT(slotMINUS()));
	connect(m_ui.btn_xor, SIGNAL(clicked()), SLOT(slotXOR()));
	connect(m_ui.btn_and, SIGNAL(clicked()), SLOT(slotAND()));
	connect(m_ui.btn_replace, SIGNAL(clicked()), SLOT(slotReplace()));
	connect(m_ui.btn_divide, SIGNAL(clicked()), SLOT(slotVolumeDivide()));
	connect(m_ui.btn_export_pos, SIGNAL(clicked()), SLOT(slotExportVoxelPositions()));
}


void 
VolumePanel::slotColorChanged()
{
	qreal w = m_colorEditor->width();
	qreal h = m_colorEditor->height();
	QPolygonF points = m_colorEditor->points();
	QPolygonF pointsConverted;

	for ( int i = 0; i < points.size(); ++i)
	{
		pointsConverted << QPointF(double(points.at(i).x())*(255.0/w), 1.0 - double(points.at(i).y())*(1.0/h));
		cout << "x=" << double(points.at(i).x())*(255.0/w) << ",y=" << 1.0 - double(points.at(i).y())*(1.0/h) << endl;
	}
}

void 
VolumePanel::slotOpacityChanged()
{
	if ( !m_vsource)
		return;

	qreal w = m_opacityEditor->width();
	qreal h = m_opacityEditor->height();
	QPolygonF points = m_opacityEditor->points();
	QPolygonF pointsConverted;


	for ( int i = 0; i < points.size(); ++i)
	{
		pointsConverted << QPointF(double(points.at(i).x())*(255.0/w), 1.0 - double(points.at(i).y())*(1.0/h));
		cout << "x=" << double(points.at(i).x())*(255.0/w) << ",y=" << 1.0 - double(points.at(i).y())*(1.0/h) << endl;
	}

	m_vsource->setVolumeOpacity(pointsConverted);
}

// void 
// VolumePanel::setDisplayFramework(DisplayFramework* display)
// {
// 	ControlPanelBase::setDisplayFramework(display);
// 
// 	connect(m_ui.btn_addSeed, SIGNAL(clicked()), display, SLOT(slotPickSeed()));
// 	connect(display, SIGNAL(emitSeedPicked(QString)), this, SLOT(slotAddSeed(QString)));
// }

void 
VolumePanel::setSource(const QModelIndex& index)
{
	ControlPanelBase::setSource(index);

	if ( !index.isValid())
		return;

	Source *source = currentSource();
	if (source->type()!=stVolume)
	{
		m_vsource=NULL;
		return;
	}

	m_vsource = (VolumeSourceBase *)source;

	QStringList list = m_vsource->childrenList();

	if ( !m_ui.btn_setVolume1->isChecked())
	{
		m_ui.le_volume1->setText(currentSource()->text());
		m_volume1 = m_vsource;
	}

	if ( !m_ui.btn_setVolume2->isChecked())
	{
		m_ui.le_volume2->setText(currentSource()->text());
		m_volume2 = m_vsource;
	}
}


void 
VolumePanel::slotVolumeCalculation()
{
	if (!m_vsource)
	{
		qDebug() << "[Warning]: Empty source";
		return;
	}

	switch (m_vsource->dataType())
	{
	case VTK_UNSIGNED_CHAR:
		volumeCalculation<unsigned char>();
		break;
	case VTK_SHORT:
		volumeCalculation<short>();
		break;
	case VTK_FLOAT:
		volumeCalculation<float>();
		break;
	default:
		qDebug() << "[Warning]: Doesn't support data type " << currentSource()->dataType();
		break;
	}
}


void VolumePanel::slotExportVoxelPositions()
{
	if (!m_vsource)
	{
		qDebug() << "[Warning]: Empty source";
		return;
	}

	QString fileName = QFileDialog::getSaveFileName(NULL, tr("Export Voxel Positions"), "", tr("Image Files (*.txt)"));
	if ( fileName.isEmpty())
		return;

	switch (m_vsource->dataType())
	{
	case VTK_UNSIGNED_CHAR:
		exportVoxelPositions<unsigned char>(fileName);
		break;
	case VTK_SHORT:
		exportVoxelPositions<short>(fileName);
		break;
	case VTK_FLOAT:
		exportVoxelPositions<float>(fileName);
		break;
	default:
		qDebug() << "[Warning]: Doesn't support data type " << currentSource()->dataType();
		break;
	}
}




void 
VolumePanel::slotVolumeDivide()
{
	if (!m_vsource)
	{
		qDebug() << "[Warning]: Empty source";
		return;
	}

	switch (m_vsource->dataType())
	{
	case VTK_UNSIGNED_CHAR:
		volumeDivide<unsigned char>();
		break;
	case VTK_SHORT:
		volumeDivide<short>();
		break;
	case VTK_FLOAT:
		volumeDivide<float>();
		break;
	default:
		qDebug() << "[Warning]: Doesn't support data type " << currentSource()->dataType();
		break;
	}
}


void 
VolumePanel::volumeOperation(VolumeOperation vo)
{
	if ( !m_volume1 || !m_volume2)
		return;

// 	if ( m_volume1->dataType() != m_volume2->dataType())
// 	{
// 		qDebug() << "Warning: The type of two volume doesn't match";
// 	}

	switch(m_volume1->dataType())
	{
	case VTK_UNSIGNED_CHAR:
		{
			switch(m_volume2->dataType())
			{
			case VTK_UNSIGNED_CHAR:
				mathOperation<unsigned char, unsigned char>(m_volume1, m_volume2, vo);break;
			case VTK_SHORT:
				mathOperation<unsigned char, short>(m_volume1, m_volume2, vo);break;
			case VTK_FLOAT:
				mathOperation<unsigned char, float>(m_volume1, m_volume2, vo);break;
			}
			break;
		}
	case VTK_SHORT:
		{
			switch(m_volume2->dataType())
			{
			case VTK_UNSIGNED_CHAR:
				mathOperation<short, unsigned char>(m_volume1, m_volume2, vo);break;
			case VTK_SHORT:
				mathOperation<short, short>(m_volume1, m_volume2, vo);break;
			case VTK_FLOAT:
				mathOperation<short, float>(m_volume1, m_volume2, vo);break;
			}
			break;
		}
	case VTK_FLOAT:
		{
			switch(m_volume2->dataType())
			{
			case VTK_UNSIGNED_CHAR:
				mathOperation<float, unsigned char>(m_volume1, m_volume2, vo);break;
			case VTK_SHORT:
				mathOperation<float, short>(m_volume1, m_volume2, vo);break;
			case VTK_FLOAT:
				mathOperation<float, float>(m_volume1, m_volume2, vo);break;
			}
			break;
		}
	default:
		qDebug() << "Does not support data type " << m_volume1->dataType();
		return;
	}
}

























